package com.baizhi.controller;

import com.baizhi.constants.RedisPrefix;
import com.baizhi.dto.UploadVideoDTO;
import com.baizhi.dto.VideoFeedDTO;
import com.baizhi.entity.User;
import com.baizhi.entity.Video;
import com.baizhi.feign.CategoriesFeign;
import com.baizhi.feign.UserFeign;
import com.baizhi.po.*;
import com.baizhi.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Random;

@RefreshScope
@RestController
@RequestMapping
public class VideosController {

    private static final Logger log = LoggerFactory.getLogger(VideosController.class);
    @Autowired
    private VideoService videoService;
    @Autowired
    private UserFeign userFeign;
    @Autowired
    private CategoriesFeign categoriesFeign;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private FollowingService followingService;
    @Autowired
    private PlayedService playedService;
    @Autowired
    private FavoriteService favoriteService;
    @Autowired
    private UserLikedService userLikedService;

    //首页视频推荐列表
    @GetMapping("recommends")
    public QueryVideo query(@RequestParam(defaultValue = "1", value = "page") Integer page, @RequestParam(value = "per_page", defaultValue = "1") Integer per_page) {
        List<Video> videos = videoService.queryByPage(page, per_page);
        Random random = new Random();
        int i = 0;
        i = random.nextInt(per_page);
        Video video = videos.get(i);

        //根据id获取对应up主
        String upName = userFeign.queryByUid(video.getUid());
        //根据分类id获取分类名
        String categoriesName = null;
        try {
            CategoriesPO categoriesPO = categoriesFeign.queryById(video.getCategoryId());
            categoriesName = categoriesPO.getName();
        } catch (Exception e) {
            categoriesName = "";
        }

        QueryVideo queryVideo = new QueryVideo();
        BeanUtils.copyProperties(video, queryVideo);
        queryVideo.setUploader(upName);

        //todo:喜欢数处理
        HashOperations hashOperations = redisTemplate.opsForHash();
        Long size = hashOperations.size("video_like_id:" + video.getId());
        log.info("首页视频推荐列表 视频喜欢数 {}", size);
        queryVideo.setLikes(size.intValue());

        try {
            queryVideo.setCategory(categoriesName);
        } catch (Exception e) {
            queryVideo.setCategory(null);

        }
        return queryVideo;
    }

    //上传视频
    @PostMapping("/user/videos")
    public InsertVideoPO upload(@RequestParam("token") String token, UploadVideoDTO uploadVideoDTO) {
        //根据token获取对应id
        User o = (User) redisTemplate.opsForValue().get(RedisPrefix.USER_TOKEN_PREFIX + token);
        InsertVideoPO insertVideoPO = videoService.insertVideo(uploadVideoDTO, o.getId());

        //发布动态
        //根据视频id调用查询该视频的方法,再进行组装
        Integer videoId = insertVideoPO.getId();
        VideoFeedDTO videoFeedDTO = videoService.queryOneByVideoId(videoId);
        userFeign.videoFeed(videoFeedDTO);
        return insertVideoPO;
    }

    /**
     * 用户上传的视频
     */
    @GetMapping("/user/videos")
    public List<InsertVideoPO> queryById(@RequestParam("token") String token) {
        /**
         * 根据token获取到对应的用户id，再根据id条件查出对应的所有视频
         */
        User user = (User) redisTemplate.opsForValue().get(RedisPrefix.USER_TOKEN_PREFIX + token);
        List<InsertVideoPO> insertVideoPOS = videoService.queryById(user.getId());
        return insertVideoPOS;
    }

    /**
     * 视频列表
     */
    @GetMapping("/videos")
    public List<QueryVideo> queryByCategoriesIdAndPage(@RequestParam(value = "page", defaultValue = "1") Integer page,
                                                       @RequestParam(value = "per_page", defaultValue = "1") Integer per_page,
                                                       @RequestParam(value = "category") Integer category) {
        /**
         * 根据category【类别】id查对应的视频数据
         */
        List<QueryVideo> queryVideos = videoService.queryByCategoriesId(page, per_page, category);
        //TODO:可以优化为将数据放入到redis中，然后随机获取,现在将直接返回
        return queryVideos;
    }

    /**
     * 视频详情
     */
    @GetMapping("videos/{video_id}")
    public VideoPO queryOneByVideoId(@RequestParam(value = "token", required = false) String token, @PathVariable("video_id") Integer video_id) {

        if (token != null) {
            //根据token获取当前用户id，
            User user = (User) redisTemplate.opsForValue().get(RedisPrefix.USER_TOKEN_PREFIX + token);
            //当前用户id
            Integer id = user.getId();
            //当前视频的详细信息
            /**
             *  todo: 视频详情未完成的功能
             *  1.根据当前用户id，去关注表中，uid = id ，follwing = 视频用户id 【单表连接】
             *  2.plays_count去播放表中，查全表video_id = 视频id 计算总和
             *  3.点赞先为null,是否不喜欢为null
             *  4.是否收藏 favorite,去收藏表中，uid = 当前用户id ，视频id= 视频id查询，如果有则收藏
             */
            VideoPO videoPO = videoService.queryByVideoId(video_id);
            //视频用户id
            Integer VideoUserId = videoPO.getUploader().getId();
            Boolean aBoolean = followingService.queryByUserIdAndVideoId(id, VideoUserId);
            //是否关注
            videoPO.getUploader().setFollowed(aBoolean);
            //播放次数
            Integer videoId = videoPO.getId();
            Integer count = playedService.queryByVideoId(videoId);
            videoPO.setPlaysCount(count);
            //收藏
            Boolean IsFavorite = favoriteService.queryByUserIdAndVideo(id, videoId);
            videoPO.setFavorite(IsFavorite);
            //点赞次数
            HashOperations hashOperations = redisTemplate.opsForHash();
            Long size = hashOperations.size("video_like_id:" + video_id);
            videoPO.setLikesCount(size.intValue());
            //是否喜欢
            Object o = hashOperations.get("video_like_id:" + video_id, "user_id:" + id);
            if (o == null) {
                //没有点赞
                videoPO.setLiked(false);
            } else {
                videoPO.setLiked(true);
            }


            //将视频放入到redis中
            redisTemplate.opsForValue().set(RedisPrefix.VIDEO_PREFIX + video_id, videoPO);
            //将视频播放添加到播放历史
            userFeign.addPlayed(id, videoId);
            return videoPO;
        } else {
            /**
             * 不能有是否关注是否收藏
             */
            VideoPO videoPO = videoService.queryByVideoId(video_id);
            //播放次数
            Integer videoId = videoPO.getId();
            Integer count = playedService.queryByVideoId(videoId);
            videoPO.setPlaysCount(count);
            return videoPO;

        }
        /*User user = (User) redisTemplate.opsForValue().get(RedisPrefix.USER_TOKEN_PREFIX + token);
        //当前用户id
        Integer id = user.getId();
        //当前视频的详细信息
        *//**
         *  todo: 视频详情未完成的功能
         *  1.根据当前用户id，去关注表中，uid = id ，follwing = 视频用户id 【单表连接】
         *  2.plays_count去播放表中，查全表video_id = 视频id 计算总和
         *  3.点赞先为null,是否不喜欢为null
         *  4.是否收藏 favorite,去收藏表中，uid = 当前用户id ，视频id= 视频id查询，如果有则收藏
         *//*
        VideoPO videoPO = videoService.queryByVideoId(video_id);
        //视频用户id
        Integer VideoUserId = videoPO.getUploader().getId();
        Boolean aBoolean = followingService.queryByUserIdAndVideoId(id, VideoUserId);
        //是否关注
        videoPO.getUploader().setFollowed(aBoolean);
        //播放次数
        Integer videoId = videoPO.getId();
        Integer count = playedService.queryByVideoId(videoId);
        videoPO.setPlaysCount(count);
        //收藏
        Boolean IsFavorite = favoriteService.queryByUserIdAndVideo(id, videoId);
        videoPO.setFavorite(IsFavorite);
        //将视频放入到redis中
        redisTemplate.opsForValue().set(RedisPrefix.VIDEO_PREFIX + video_id, videoPO);
        return videoPO;*/
    }

    /**
     * 视频播放
     */
    @PutMapping("/user/played/{video_id}")
    public String video(@PathVariable("video_id") Integer id) {
        //如果redis中有对应的视频键，直接取出
        VideoPO videoPO = (VideoPO) redisTemplate.opsForValue().get(RedisPrefix.VIDEO_PREFIX + id);
        String link = videoPO.getLink();
        return link;
    }

    /**
     * 根据视频id获取对应的视频信息
     */
    @GetMapping("videos/feed/{videoId}")
    public FeedVideoPO queryByVideosId(@PathVariable("videoId") Integer id) {
        FeedVideoPO feedVideoPO = videoService.queryByVideosId(id);
        return feedVideoPO;
    }

    /**
     * 视频点赞
     * /user/liked/:video_id
     */
    @PutMapping("/user/liked/{video_id}")
    public void UserLiked(@PathVariable("video_id") Integer videoId, @RequestParam("token") String token) {
        //根据token获取到用户数据
        User user = (User) redisTemplate.opsForValue().get(RedisPrefix.USER_TOKEN_PREFIX + token);
        userLikedService.userLike(user.getId(), videoId);
    }


    /**
     * 视频取消点赞
     */
    @DeleteMapping("/user/liked/{video_id}")
    public void UserLikedDelete(@PathVariable("video_id") Integer videoId, @RequestParam("token") String token) {
        //根据token获取到用户数据
        User user = (User) redisTemplate.opsForValue().get(RedisPrefix.USER_TOKEN_PREFIX + token);
        userLikedService.userLikeDelete(user.getId(), videoId);
    }

    /**
     * /user/disliked/:video_id
     */
    @PutMapping("/user/disliked/{video_id}")
    public void disliked(@PathVariable("video_id") Integer videoId, @RequestParam("token") String token) {
        //根据token获取到用户数据
        User user = (User) redisTemplate.opsForValue().get(RedisPrefix.USER_TOKEN_PREFIX + token);
        userLikedService.userDisLike(user.getId(), videoId);
    }

    @DeleteMapping("/user/disliked/{video_id}")
    public void dislikedDelete(@PathVariable("video_id") Integer videoId, @RequestParam("token") String token) {
        //根据token获取到用户数据
        User user = (User) redisTemplate.opsForValue().get(RedisPrefix.USER_TOKEN_PREFIX + token);
        userLikedService.userDisLikeDelete(user.getId(), videoId);
    }

    /**
     * /user/favorites/:video_id
     */
    @PutMapping("/user/favorites/{video_id}")
    public void favoritesAdd(@PathVariable("video_id") Integer videoId, @RequestParam("token") String token) {
        //根据token获取到用户数据
        User user = (User) redisTemplate.opsForValue().get(RedisPrefix.USER_TOKEN_PREFIX + token);
        //当前用户id
        Integer id = user.getId();
        log.info("id {}", id);
        favoriteService.insertFavoriter(id, videoId);
    }

    /**
     * 视频取消收藏
     * /user/favorites/:video_id
     */
    @DeleteMapping("/user/favorites/{video_id}")
    public void FavoritesDelete(@PathVariable("video_id") Integer videoId, @RequestParam("token") String token) {
        //根据token获取到用户数据
        User user = (User) redisTemplate.opsForValue().get(RedisPrefix.USER_TOKEN_PREFIX + token);
        //当前用户id
        Integer id = user.getId();
        //删除收藏
        favoriteService.deleteFavoriter(id, videoId);
    }


    /**
     * 查询所有视频，为给es添加数据,
     * todo:有时间可以优化给后台系统，后台管理员进行操作
     */
    @GetMapping("videos/queryAllVideos")
    public List<VideoES> queryAllVideos() {
        List<VideoES> videoES = videoService.queryAllVideosForES();
        return videoES;
    }
}
